import { ref } from 'vue';
import { defineStore } from 'pinia';
import type {
  billType,
  optionType,
  paymentListType,
  tapType,
} from '@/types/bill';

//option默认配置
// {
//   dayQuota: 30,
//   tap: [
//     {
//       name: '早餐',
//       background: 'rgb(87,189,105)',
//       color: 'rgb(255,255,255)',
//     },
//     {
//       name: '午餐',
//       background: 'rgb(128,205,250)',
//       color: 'rgb(255,255,255)',
//     },
//   ],
// }

export const useBillStore = defineStore(
  'bill',
  () => {
    //响应式数据
    const bill = ref<billType>([]);
    const option = ref<optionType>({
      dayQuota: 30,
      tap: [],
    });

    function GetBill() {
      return bill.value;
    }
    function SetBill(data: billType) {
      bill.value = data;
    }
    //获取配置
    function GetOption() {
      return option.value;
    }
    function SetOption(data: optionType) {
      option.value = data;
    }

    // 获取日历
    function GetMonth(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
    ) {
      //获取索引，如果没有则添加日期并返回索引
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      return {
        ...bill.value[index.yearIndex],
        ...bill.value[index.yearIndex].months[index.monthIndex],
        monthData: { ...bill.value[index.yearIndex].months[index.monthIndex] },
        dayData: {
          ...bill.value[index.yearIndex].months[index.monthIndex].days[
            index.dayIndex
          ],
        },
        ...bill.value[index.yearIndex].months[index.monthIndex].days[
          index.dayIndex
        ],
      };
    }

    //获取指定日期的账单
    function GetDayData(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
    ) {
      //获取索引，如果没有则添加日期并返回索引
      const index = GetIndex(yearTemp, monthTemp, dayTemp);

      // 获取日操作数据
      GetDayCost(yearTemp, monthTemp, dayTemp);

      // 获取月操作数据
      GetMonthData(yearTemp, monthTemp, dayTemp);

      //获取月积攒
      return {
        ...bill.value[index.yearIndex],
        ...bill.value[index.yearIndex].months[index.monthIndex],
        monthData: { ...bill.value[index.yearIndex].months[index.monthIndex] },
        dayData: {
          ...bill.value[index.yearIndex].months[index.monthIndex].days[
            index.dayIndex
          ],
        },
        ...bill.value[index.yearIndex].months[index.monthIndex].days[
          index.dayIndex
        ],
      };
    }

    //获取年月日在bill的索引
    function GetIndex(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
    ) {
      let yearItem = null;
      let monthItem = null;
      let dayItem = null;
      bill.value.map((item, index) => {
        if (item.year === yearTemp) {
          yearItem = index;
          item.months.map((item1, index1) => {
            if (item1.month === monthTemp) {
              monthItem = index1;
              item1.days.map((item2, index2) => {
                if (item2.day === dayTemp) {
                  dayItem = index2;
                }
              });
            }
          });
        }
      });
      if (yearItem === null) {
        bill.value.push({
          year: yearTemp,
          accumulate: 0,
          months: [],
        });
        yearItem = bill.value.length - 1;
      }

      if (monthItem === null) {
        bill.value[yearItem].months.push({
          month: monthTemp,
          accumulate: 0,
          receipts: 0,
          limit: 0,
          dayLimit: option.value.dayQuota,
          cost: 0,
          residue: 0,
          days: [],
        });
        monthItem = bill.value[yearItem].months.length - 1;
        bill.value[yearItem].months[monthItem].limit =
          option.value.dayQuota * getDaysInMonth(yearItem, monthItem);
        bill.value[yearItem].months[monthItem].residue =
          option.value.dayQuota * getDaysInMonth(yearItem, monthItem);
      }
      if (dayItem === null) {
        bill.value[yearItem].months[monthItem].days.push({
          day: dayTemp,
          limit: bill.value[yearItem].months[monthItem].dayLimit,
          cost: 0,
          receipts: 0,
          residue: bill.value[yearItem].months[monthItem].dayLimit,
          paymentList: [],
        });
        dayItem = bill.value[yearItem].months[monthItem].days.length - 1;
      }
      return {
        yearIndex: yearItem,
        monthIndex: monthItem,
        dayIndex: dayItem,
      };
    }

    //添加消费项
    function AddDayBill(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
      object: paymentListType,
    ) {
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      bill.value[index.yearIndex].months[index.monthIndex].days[
        index.dayIndex
      ].paymentList.push(object);
    }

    //删除消费项
    function DelDayBill(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
      indexTemp: number,
    ) {
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      bill.value[index.yearIndex].months[index.monthIndex].days[
        index.dayIndex
      ].paymentList.splice(indexTemp, 1);
    }

    //修改消费项
    function ModBill(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
      object: paymentListType,
      indexTemp: number,
    ) {
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      bill.value[index.yearIndex].months[index.monthIndex].days[
        index.dayIndex
      ].paymentList[indexTemp] = object;
    }
    //修改单日限额
    function dayLimit(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
      value: number = 30,
    ) {
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      const tempLimit =
        bill.value[index.yearIndex].months[index.monthIndex].days[
          index.dayIndex
        ].limit;
      bill.value[index.yearIndex].months[index.monthIndex].days[
        index.dayIndex
      ].limit = value;
      bill.value[index.yearIndex].months[index.monthIndex].limit +=
        value - tempLimit;
    }

    //修改当月每日默认限额
    function monthLimit(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
      value: number = 30,
    ) {
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      const residueDayNum =
        getDaysInMonth(index.yearIndex, index.monthIndex) - dayTemp + 1;
      let cmdDayLimitNum = 0;
      const oldDayLimit =
        bill.value[index.yearIndex].months[index.monthIndex].dayLimit;
      bill.value[index.yearIndex].months[index.monthIndex].dayLimit = value;
      bill.value[index.yearIndex].months[index.monthIndex].days.forEach(
        (item) => {
          if (item.day >= dayTemp) {
            dayLimit(yearTemp, monthTemp, item.day, value);
            cmdDayLimitNum++;
          }
        },
      );
      bill.value[index.yearIndex].months[index.monthIndex].limit +=
        (residueDayNum - cmdDayLimitNum) * (value - oldDayLimit);
    }

    //修改每日默认限额
    function yearLimit(
      yearTemp: number = 0,
      monthTemp: number = 0,
      dayTemp: number = 0,
      value: number = 30,
    ) {
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      option.value.dayQuota = value;
      bill.value[index.yearIndex].months.forEach((item) => {
        if (item.month >= monthTemp) {
          monthLimit(yearTemp, monthTemp, dayTemp, value);
        }
      });
    }

    //添加配置标签
    function AddTap(object: tapType) {
      option.value.tap.push(object);
    }
    //删除配置标签
    function DelTap(index: number) {
      option.value.tap.splice(index, 1);
    }
    //修改配置标签

    //清除所有数据
    function Clear() {
      bill.value = [];
      option.value = {
        dayQuota: 30,
        tap: [],
      };
    }

    //计算日操作数据
    function GetDayCost(yearTemp: number, monthTemp: number, dayTemp: number) {
      let costtemp = 0;
      let receiptsTemp = 0;
      const index = GetIndex(yearTemp, monthTemp, dayTemp);
      const dayData = bill.value[index.yearIndex].months[index.monthIndex].days;
      dayData[index.dayIndex].paymentList.forEach((item) => {
        const priceTemp = Number(item.price);
        if (priceTemp > 0) {
          costtemp += priceTemp;
        } else if (priceTemp < 0) {
          receiptsTemp += priceTemp;
        }
      });
      dayData[index.dayIndex].cost = Number(costtemp.toFixed(2));
      dayData[index.dayIndex].receipts = Number((-receiptsTemp).toFixed(2));
      dayData[index.dayIndex].residue = Number(
        (
          dayData[index.dayIndex].limit -
          dayData[index.dayIndex].cost +
          dayData[index.dayIndex].receipts
        ).toFixed(2),
      );
    }

    // 计算月操作数据
    function GetMonthData(
      yearTemp: number,
      monthTemp: number,
      dayTemp: number,
    ) {
      // 获取今日
      const todayTemp = new Date();
      const month = todayTemp.getMonth() + 1;
      const day = todayTemp.getDate();

      // 获取当月索引组
      const index = GetIndex(yearTemp, monthTemp, dayTemp);

      let costTemp = 0;
      let receipts = 0;
      let accumulate = 0;
      // 如果是当月则收集到今天
      if (month === monthTemp) {
        bill.value[index.yearIndex].months[index.monthIndex].days.filter(
          (item) => {
            if (item.day <= day) {
              costTemp += item.cost ?? 0;
              receipts += item.receipts ?? 0;
              accumulate += -item.cost + (item.limit + (item.receipts ?? 0));
            }
          },
        );
        // 如果不是当月则收集该月份全部数据
      } else {
        bill.value[index.yearIndex].months[index.monthIndex].days.filter(
          (item) => {
            costTemp += item.cost ?? 0;
            receipts += item.receipts ?? 0;
            accumulate += -item.cost + (item.limit + (item.receipts ?? 0));
          },
        );
      }
      bill.value[index.yearIndex].months[index.monthIndex].cost = Number(
        costTemp.toFixed(2),
      );
      bill.value[index.yearIndex].months[index.monthIndex].receipts = Number(
        receipts.toFixed(2),
      );
      bill.value[index.yearIndex].months[index.monthIndex].residue = Number(
        (
          bill.value[index.yearIndex].months[index.monthIndex].limit -
          bill.value[index.yearIndex].months[index.monthIndex].cost +
          bill.value[index.yearIndex].months[index.monthIndex].receipts
        ).toFixed(2),
      );
      bill.value[index.yearIndex].months[index.monthIndex].accumulate = Number(
        accumulate.toFixed(2),
      );
    }

    //获取当前年月的天数
    function getDaysInMonth(year: number, month: number) {
      return new Date(
        bill.value[year].year,
        bill.value[year].months[month].month,
        0,
      ).getDate();
    }

    //外部可访问
    return {
      bill,
      option,
      GetBill,
      SetBill,
      SetOption,
      GetDayData,
      Clear,
      AddDayBill,
      AddTap,
      GetOption,
      DelTap,
      DelDayBill,
      ModBill,
      GetDayCost,
      getDaysInMonth,
      GetMonth,
      dayLimit,
      monthLimit,
      yearLimit,
    };
  },
  {
    //网页端配置
    //persist: true,
    //小程序端配置
    persist: {
      storage: {
        getItem(key) {
          return uni.getStorageSync(key);
        },
        setItem(key, value) {
          return uni.setStorageSync(key, value);
        },
      },
    },
  },
);
